{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Functions\n",
    "\n",
    "**Time**\n",
    "\n",
    "- Teaching: 10 min\n",
    "- Exercises: 15 min\n",
    "\n",
    "**Questions**:\n",
    "\n",
    "- \"How can I avoid rewriting code that I will use again?\"\n",
    "\n",
    "**Learning Objectives**:\n",
    "\n",
    "- \"Understand what a function is and why it's helpful.\"\n",
    "- \"Understand how to define a function and its arguments.\"\n",
    "- \"Understand what `return` does.\"\n",
    "- \"Write a basic function.\"\n",
    "* * * * *"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Functions are the basic building blocks of programs.\n",
    "\n",
    "* Functions are the basic building blocks that we use to store chunks of code we'll want to use again later. \n",
    "* Specifically, they do three things:\n",
    "    1. They name pieces of code the way variables name strings and numbers.\n",
    "    2. They take arguments, or data that you want to do something on.\n",
    "    3. Using 1 and 2 they let you make your own \"mini-scripts\" or \"tiny commands.\"\n",
    "* The details are pretty simple, but this is one of those ideas where it's good to get lots of practice!\n",
    "    \n",
    "\n",
    "## Define a function using `def` with a name, parameters, and a block of code.\n",
    "\n",
    "*   Begin the definition of a new function with `def`.\n",
    "*   Followed by the name of the function.\n",
    "    *   Must obey the same rules as variable names.\n",
    "*   The *parameters* are defined in parentheses.\n",
    "    *   Empty parentheses if the function doesn't take any inputs.\n",
    "    *   We will discuss this in detail in a moment.\n",
    "*   Then a colon.\n",
    "*   Then an indented block of code."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def print_greeting():\n",
    "    print('Hello!')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Defining a function does not run it!!!\n",
    "\n",
    "*   Defining a function does not run it.\n",
    "    *   Like assigning a value to a variable.\n",
    "*   Must call the function to execute the code it contains.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print_greeting()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Arguments in call are matched to parameters in definition.\n",
    "\n",
    "*   Functions are most useful when they can operate on different data.\n",
    "*   Specify *parameters* when defining a function.\n",
    "    *   These become variables when the function is executed.\n",
    "    *   Are assigned the arguments in the call (i.e., the values passed to the function).\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def print_date(year, month, day):\n",
    "    joined = str(year) + '/' + str(month) + '/' + str(day)\n",
    "    print(joined)\n",
    "\n",
    "print_date(1871, 3, 19)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*   Via [Twitter](https://twitter.com/minisciencegirl/status/693486088963272705):\n",
    "    `()` contains the ingredients for the function\n",
    "    while the [body](https://github.com/dlab-berkeley/python-intensive/blob/master/Glossary.md#body) contains the recipe.\n",
    "\n",
    "## Functions may return a result to their caller using `return`.\n",
    "\n",
    "*   Use `return ...` to give one (and only one) value back to the caller.\n",
    "*   May occur anywhere in the function.\n",
    "*   But functions are easier to understand if `return` occurs:\n",
    "    *   At the start to handle special cases.\n",
    "    *   At the very end, with a final result.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def average(values):\n",
    "    if len(values) == 0:\n",
    "        return None\n",
    "    return sum(values) / len(values)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "a = average([1, 3, 4])\n",
    "print('average of actual values:', a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print('average of empty list:', average([]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*   Remember: [every function returns something](https://github.com/dlab-berkeley/python-intensive/blob/master/Day_1/06_Built-ins.ipynb).\n",
    "*   A function that doesn't explicitly `return` a value automatically returns `None`.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "result = print_date(1871, 3, 19)\n",
    "print('result of call is:', result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Challenge 1: Definition and Use\n",
    "\n",
    "What does the following program print? Why?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def pressure(value):\n",
    "    print('pressure is', str(value))\n",
    "    \n",
    "print(pressure, 22.5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "What do you think the intent behind this program was, and how would you fix the code to match it?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Challenge 2: Change the Names\n",
    "\n",
    "Fill in the blanks to create a function that takes a name like \"Rochelle Terman\" and returns that name in uppercase and reversed, like \"TERMAN, ROCHELLE\". Then call the function and print the name."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def long_function(name_string):\n",
    "    upper_case = name_string.____ # make upper\n",
    "    upper_case_list = upper_case._____ # turn into a list\n",
    "    first_name = ______ # take first name\n",
    "    last_name = _______ # take last name\n",
    "    reversed_name = ________ # reverse and separate by a comma and space\n",
    "    return(reversed_name)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Challenge 3: Order of Operations\n",
    "\n",
    "See what the following programs prints"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "result = print_date(1871, 3, 19)\n",
    "print('result of call is:', result)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Explain why the two lines of output appeared in the order they did."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Challenge 4: Calling by Name\n",
    "\n",
    "What does this short program print?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def print_date(year, month, day):\n",
    "    joined = str(year) + '/' + str(month) + '/' + str(day)\n",
    "    print(joined)\n",
    "\n",
    "print_date(day=1, month=2, year=2003)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "When and why is it useful to call functions this way?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Challenge 5: Find the substring\n",
    "\n",
    "In our project, we'll be dealing with texts like this (from Djibouti's 2013 review):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "rec_1 = \"143.1 Pursue efforts to ratify international human rights instruments (Kuwait);\" \n",
    "rec_2 = \"143.2 Ratify the international human rights instruments to which Djibouti is not yet party (Niger);\" \n",
    "rec_3 = \"143.3 Carry on with the ratification of international conventions (Democratic Republic of Congo);\" \n",
    "rec_4 = \"143.4 Speed up measures aimed at ratifying the Optional Protocol to CEDAW (Republic of Moldova);\" "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As you see, the recommending country is always at the end of the line in parentheses.\n",
    "\n",
    "Write a function that accepts a recommendation (a string) and returns the recommending country (also a string)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_country:\n",
    "    # your code here\n",
    "\n",
    "# uncomment to test your code\n",
    "get_country(rec_1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Modify the function above to return a [`tuple`](http://www.tutorialspoint.com/python/python_tuples.htm) with element 0 being the country name, and element 1 being the recommendation as a string:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def get_country_rec:\n",
    "    # your code here\n",
    "\n",
    "\n",
    "# uncomment to test your code\n",
    "get_country_rec(rec_1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "*****\n",
    "## Keypoints\n",
    "\n",
    "1. Functions are the basic building blocks of programs.\n",
    "2. Define a function using `def` with a name, parameters, and a block of code.\n",
    "3. Defining a function does not run it\n",
    "4. Arguments in call are matched to parameters in definition.\n",
    "5. Functions may return a result to their caller using return."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
